home *** CD-ROM | disk | FTP | other *** search
- // ActiveCtl.h : Declaration of the CActiveDoc class
- //
- // This is a part of the Active Template Library.
- // Copyright (C) 1996-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Active Template Library Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Active Template Library product.
-
- #include "resource.h" // main symbols
- #include "OleDocument.h"
- #include "Menu.h"
- #include "ToolBar.h"
- #include <RichEdit.h>
-
- /////////////////////////////////////////////////////////////////////////////
- // CActiveDoc
- class CActiveDoc :
- public CComObjectRoot,
- public CComCoClass<CActiveDoc, &CLSID_CActiveDoc>,
- public CComControl<CActiveDoc>,
- public IDispatchImpl<IActiveDoc, &IID_IActiveDoc, &LIBID_ACTIVEDOCLib>,
- public IProvideClassInfo2Impl<&CLSID_CActiveDoc, NULL, &LIBID_ACTIVEDOCLib>,
- public IPersistStreamInitImpl<CActiveDoc>,
- public IPersistStorageImpl<CActiveDoc>,
- public IQuickActivateImpl<CActiveDoc>,
- public IOleControlImpl<CActiveDoc>,
- public IOleObjectImpl<CActiveDoc>,
- public IOleInPlaceActiveObjectImpl<CActiveDoc>,
- public IViewObjectExImpl<CActiveDoc>,
- public IOleInPlaceObjectWindowlessImpl<CActiveDoc>,
- public IDataObjectImpl<CActiveDoc>,
- public ISupportErrorInfo,
- public IOleDocumentImpl<CActiveDoc>,
- public IOleDocumentViewImpl<CActiveDoc>,
- public CMenu<CActiveDoc>,
- public CToolbar<CActiveDoc>,
- public IPersistFile
- {
- public:
- CActiveDoc() :
- m_wndRTF(_T("RichEdit"), this, 1)
- {
- m_wndRTF.m_hWnd = NULL;
- m_bWindowOnly = TRUE;
- }
-
- DECLARE_REGISTRY_RESOURCEID(IDR_ActiveDoc)
-
- BEGIN_COM_MAP(CActiveDoc)
- COM_INTERFACE_ENTRY(IActiveDoc)
- COM_INTERFACE_ENTRY(IDispatch)
- COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
- COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
- COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
- COM_INTERFACE_ENTRY_IMPL(IOleControl)
- COM_INTERFACE_ENTRY_IMPL(IOleObject)
- COM_INTERFACE_ENTRY_IMPL(IQuickActivate)
- COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
- COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
- COM_INTERFACE_ENTRY_IMPL(IDataObject)
- COM_INTERFACE_ENTRY(IOleDocument)
- COM_INTERFACE_ENTRY(IOleDocumentView)
- COM_INTERFACE_ENTRY(IProvideClassInfo)
- COM_INTERFACE_ENTRY(IProvideClassInfo2)
- COM_INTERFACE_ENTRY(ISupportErrorInfo)
- COM_INTERFACE_ENTRY(IPersistFile)
- END_COM_MAP()
-
- BEGIN_PROPERTY_MAP(CActiveDoc)
- // PROP_ENTRY("Description", dispid, clsid)
- END_PROPERTY_MAP()
-
- BEGIN_MSG_MAP(CActiveDoc)
- MESSAGE_HANDLER(WM_PAINT, OnPaint)
- MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
- MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
- MESSAGE_HANDLER(WM_CREATE, OnCreate)
- MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
- MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackgnd)
- COMMAND_RANGE_HANDLER(ID_BLACK, ID_BLUE, OnColorChange)
- COMMAND_ID_HANDLER(ID_HELP_ABOUT, OnHelpAbout)
- NOTIFY_CODE_HANDLER(TTN_NEEDTEXT, OnToolbarNeedText)
-
- ALT_MSG_MAP(1)
- END_MSG_MAP()
-
- BEGIN_TOOLBAR_MAP(CActiveDoc)
- TOOLBAR_BUTTON(ID_BLACK)
- TOOLBAR_BUTTON(ID_RED)
- TOOLBAR_BUTTON(ID_GREEN)
- TOOLBAR_BUTTON(ID_BLUE)
- TOOLBAR_SEPARATOR()
- TOOLBAR_BUTTON(ID_HELP_ABOUT)
- END_TOOLBAR_MAP()
-
- // ISupportsErrorInfo
- STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
-
- // IActiveDoc
- public:
-
- // Override SetClientSite
- HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite)
- {
- // If we currently have a document site pointer, release it.
- m_spDocSite.Release();
- m_bDocObject=FALSE;
-
- if (pClientSite != NULL)
- {
- pClientSite->QueryInterface(&m_spDocSite);
- if (m_spDocSite != NULL)
- m_bDocObject = true;
- }
- return CComControlBase::IOleObject_SetClientSite(pClientSite);
- }
-
- // Override DoVerb
- STDMETHOD(DoVerb)(LONG iVerb, LPMSG pMsg, IOleClientSite* pActiveSite, LONG lindex,
- HWND hwndParent, LPCRECT lprcPosRect)
- {
- // Check if we should activate as a docobject or not
- // (client supports IOleDocumentSite)
- if (m_bDocObject)
- {
- switch (iVerb)
- {
- case OLEIVERB_SHOW:
- case OLEIVERB_OPEN:
- case OLEIVERB_UIACTIVATE:
- if (!m_bUIActive)
- return m_spDocSite->ActivateMe(NULL);
- break;
- }
- }
- return IOleObjectImpl<CActiveDoc>::DoVerb(iVerb, pMsg, pActiveSite, lindex, hwndParent, lprcPosRect);
- }
-
- STDMETHOD(InPlaceDeactivate)(void)
- {
- // Release the pointers we have no need for now.
- m_spDocSite.Release();
- m_spInPlaceFrame.Release();
-
- return IOleInPlaceObjectWindowlessImpl<CActiveDoc>::InPlaceDeactivate();
- }
-
- // Override IOleInPlaceActiveObjectImpl::OnDocWindowActivate
- STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
- {
- ATLTRACE(_T("CActiveDoc::OnDocWindowActivate\n"));
- if (fActivate)
- {
- InPlaceMenuCreate();
- SetupToolbar(NULL);
- }
- else
- {
- DestroyToolbar();
- InPlaceMenuDestroy();
- }
- return S_OK;
- }
- STDMETHOD(TranslateAccelerator)(MSG *pMsg)
- {
- ATLTRACE(_T("CActiveDoc::TranslateAccelerator\n"));
-
- if (pMsg == NULL)
- return E_POINTER;
-
- if (m_spInPlaceFrame != NULL)
- return OleTranslateAccelerator(m_spInPlaceFrame, &m_frameInfo, pMsg);
- else
- return S_FALSE;
- }
- // Override IPersistStorageImpl::IsDirty
- STDMETHOD(IsDirty)()
- {
- ATLTRACE(_T("CActiveDoc::IsDirty\n"));
- if (m_wndRTF.m_hWnd != NULL)
- {
- return (m_wndRTF.SendMessage(EM_GETMODIFY, 0, 0)) ? S_OK : S_FALSE;
- }
- else
- return S_FALSE;
- }
- // Override IPersistStreamInitImp::Save
- STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty)
- {
- ATLTRACE(_T("CActiveDoc::Save\n"));
- // We can only save if we have an RTF control to save data from
- if (m_wndRTF.m_hWnd != NULL)
- {
- EDITSTREAM es;
- es.dwCookie = (DWORD)pStm;
- es.dwError = 0;
- es.pfnCallback = RTFSave;
- m_wndRTF.SendMessage(EM_STREAMOUT, SF_RTF, (LPARAM)&es);
- if (fClearDirty)
- SetRTFModified(FALSE); // We're no longer dirty
- }
- return S_OK;
- }
- // Override IPersistStreamInitImp::Load
- STDMETHOD(Load)(LPSTREAM pStm)
- {
- ATLTRACE(_T("CActiveDoc::Load\n"));
- // Ensure the RTF window has been created, so that we can load data into it.
- if (m_wndRTF.m_hWnd == NULL)
- CreateRTFWindow();
-
- EDITSTREAM es;
- es.dwCookie = (DWORD)pStm;
- es.dwError = 0;
- es.pfnCallback = RTFLoad;
- m_wndRTF.SendMessage(EM_STREAMIN, SF_RTF, (LPARAM)&es);
- SetRTFModified(FALSE); // We're not dirty
- return S_OK;
- }
- static DWORD CALLBACK RTFSave(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
- {
- HRESULT hr;
- LPSTREAM pStm = (LPSTREAM)dwCookie;
-
- hr = pStm->Write(pbBuff, cb, (ULONG*)pcb);
- if (SUCCEEDED(hr))
- return 0;
- else
- return 1; // Failed so stop calling us.
- }
- static DWORD CALLBACK RTFLoad(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
- {
- HRESULT hr;
- LPSTREAM pStm = (LPSTREAM)dwCookie;
-
- hr = pStm->Read(pbBuff, cb, (ULONG*)pcb);
- if (SUCCEEDED(hr))
- return 0;
- else
- return 1; // Failed so stop calling us.
- }
-
- HRESULT OnDraw(ATL_DRAWINFO& /* di */)
- {
- // Drawing handled by RTF control
- return 0;
- }
- LRESULT OnEraseBackgnd(UINT, WPARAM, LPARAM, BOOL&)
- {
- return 0;
- }
- LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&)
- {
- // If we haven't created the RTF window then we need to create it. If not, is has already
- // been created by the Load procedure so we just make sure it is a parent of our window.
- if (m_wndRTF.m_hWnd == NULL)
- CreateRTFWindow();
- else
- {
- m_wndRTF.ModifyStyle(WS_POPUP, WS_CHILD | WS_VISIBLE);
- m_wndRTF.SetParent(m_hWnd);
- }
- return 0;
- }
- LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&)
- {
- // Destroy RTF window and unload the DLL
- m_wndRTF.DestroyWindow();
- FreeLibrary(m_hLibRTF);
- return 0;
- }
- LRESULT OnSetFocus(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- // When the control window get's the focus, set the focus to the
- // RTF control.
- CComControl<CActiveDoc>::OnSetFocus(nMsg, wParam, lParam, bHandled);
- m_wndRTF.SetFocus();
- return 0;
- }
- void CreateRTFWindow()
- {
- DWORD dwStyle;
- RECT rc;
- // If the control window has been created then we can use it's size otherwise default
- // to zero.
- if (m_hWnd == NULL)
- {
- // If the window isn't going to be a child at the moment, then don't set
- // WS_CHILD and don't make it visible yet
- dwStyle = WS_POPUP;
- ZeroMemory(&rc, sizeof(RECT));
- }
- else
- {
- dwStyle = WS_CHILD | WS_VISIBLE;
- GetWindowRect(&rc);
- rc.right -= rc.left;
- rc.bottom -= rc.top;
- rc.top = rc.left = 0;
- }
- m_hLibRTF = LoadLibrary(_T("RICHED32.DLL"));
- m_wndRTF.Create(m_hWnd, rc, NULL, dwStyle | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL, 0);
- ATLASSERT(m_wndRTF != NULL);
- }
- void SetRTFModified(BOOL bModified)
- {
- if (m_wndRTF.m_hWnd != NULL)
- {
- m_wndRTF.SendMessage(EM_SETMODIFY, (WPARAM)bModified, 0);
- }
- }
- // IOleInPlaceActiveObject::ResizeBorder
- STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow* /* pUIWindow */, BOOL /* bFrameWindow */)
- {
- ATLTRACE(_T("CActiveDoc::ResizeBorder\n"));
-
- MoveToolbar(prcBorder);
-
- return S_OK;
- }
- STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
- {
- ATLTRACE("CActiveDoc::SetObjectRects(%d, %d, %d, %d)\n", prcPos->left, prcPos->top, prcPos->right, prcPos->bottom);
-
- MoveToolbar();
-
- // When our control window moves, move the toolbar and the RTF window.
- IOleInPlaceObjectWindowlessImpl<CActiveDoc>::SetObjectRects(prcPos, prcClip);
-
- // Move the RTF control
- if (m_wndRTF.m_hWnd != NULL)
- {
- m_wndRTF.SetWindowPos(NULL, 0, 0, prcPos->right - prcPos->left, prcPos->bottom - prcPos->top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
- return S_OK;
- }
- HRESULT OnColorChange(WORD, WORD nID, HWND, BOOL&)
- {
- COLORREF col[4] =
- {
- RGB(0, 0, 0), // Black
- RGB(255, 0, 0), // Red
- RGB(0, 255, 0), // Green
- RGB(0, 0, 255) // Blue
- };
- CHARFORMAT cf;
- int nColor;
- nColor = nID - ID_BLACK;
- ATLASSERT(nColor >=0 && nColor <= sizeof(col)/sizeof(COLORREF));
- cf.cbSize = sizeof(CHARFORMAT);
- cf.dwMask = CFM_COLOR;
- cf.dwEffects = 0;
- cf.crTextColor = col[nColor];
- m_wndRTF.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
- return 0;
- }
-
-
- // IPersistFile
- STDMETHODIMP GetClassID(CLSID* pClassID)
- {
- *pClassID = GetObjectCLSID();
- return S_OK;
- }
-
- STDMETHOD(Load)(LPCOLESTR pszFileName, DWORD dwMode)
- {
- USES_CONVERSION;
- HRESULT hr;
- CComPtr<IStorage> spStorage;
-
- hr = ::StgOpenStorage(OLE2CW(pszFileName), NULL,
- dwMode,
- NULL, 0, &spStorage);
- if (FAILED(hr))
- return hr;
-
- // If the load fails we'll just start with an empty document
- IPersistStorageImpl<CActiveDoc>::Load(spStorage);
-
- return S_OK;
- }
-
- STDMETHOD(Save)(LPCOLESTR pszFileName, BOOL /* fRemember */)
- {
- USES_CONVERSION;
- HRESULT hr;
- CComPtr<IStorage> spStorage;
-
- hr = ::StgOpenStorage(OLE2CW(pszFileName), NULL,
- STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
- NULL, 0, &spStorage);
-
- return IPersistStorageImpl<CActiveDoc>::Save(spStorage, false);
- }
-
- STDMETHOD(SaveCompleted)(LPCOLESTR /* pszFileName */) { return S_OK; }
-
- STDMETHOD(GetCurFile)(LPOLESTR* /* ppszFileName */) { return E_NOTIMPL; }
-
- class CAboutDlg : public CDialogImpl<CAboutDlg>
- {
- public:
- enum { IDD = IDD_ABOUT };
- BEGIN_MSG_MAP(CAboutDlg)
- COMMAND_ID_HANDLER(IDOK, OnOK)
- END_MSG_MAP()
- HRESULT OnOK(WORD, WORD, HWND, BOOL&)
- {
- EndDialog(0);
- return 0;
- }
- };
- HRESULT OnHelpAbout(WORD, WORD, HWND, BOOL&)
- {
- CAboutDlg dlg;
- dlg.DoModal();
- return 0;
- }
-
- // Data
- CContainedWindow m_wndRTF;
- HINSTANCE m_hLibRTF;
- bool m_bDocObject;
- CComPtr<IOleDocumentSite> m_spDocSite;
- CComPtr<IOleInPlaceFrame> m_spInPlaceFrame;
- OLEINPLACEFRAMEINFO m_frameInfo;
- };
-